/**
 * 
 */
package org.dragonfire.dasm.preprocessor.blockDefs;

import org.dragonfire.dasm.Command;
import org.dragonfire.dasm.CompileException;
import org.dragonfire.dasm.preprocessor.Block;
import org.dragonfire.dasm.preprocessor.BlockDef;
import org.dragonfire.dasm.preprocessor.Preprocessor;
import org.dragonfire.util.DString;

import com.stevesoft.pat.Regex;

/**
 * @author dandroid
 * @date Dec 7, 2006
 */
public class IfBlockDef extends BlockDef {

	public Block createBlock(Preprocessor prep, Command c) {
		IfBlock ib = new IfBlock(c.getParam(0));
		ib.setName(c.getName());
		return ib;
	}

	public static class IfBlock extends Block {

		private boolean elseUsed = false;
		private boolean used = false;

		public void parsePersonalDirective(Preprocessor prep, Command c) {
			String name = c.getName();
			if (name.equalsIgnoreCase("else")) {
				if (elseUsed)
					throw new CompileException("ERROR_ELSE_INVALID_USE");
				prep.setParsing(!used);
				elseUsed = true;
			}
			else if (name.equals("elseif")) {
				if (elseUsed) {
					prep.setParsing(false);
					return;
				}
				if (!used && prep.getCompiler().evalBool(c.getParam(0))) {
					prep.setParsing(true);
					used = true;
				}
				else
					prep.setParsing(false);
			}
			else if (name.equalsIgnoreCase("if")) {
				if (prep.getCompiler().evalBool(c.getParam(0))) {
					prep.setParsing(true);
					used = true;
				}
				else
					prep.setParsing(false);
			}
			else if (name.equalsIgnoreCase("ifdef")) {
				String var = c.getParam(0);
				if (!prep.getCompiler().getBooleanParam("compat-tasm")) {
					var = prep.getCompiler().evalString(var);
				}
				if (!Regex.matches("(??word)", var))
					throw new CompileException("ERROR_VAR_REQUIRED", var);
				if (prep.getCompiler().isDefined(var)) {
					prep.setParsing(true);
					used = true;
				}
				else
					prep.setParsing(false);
			}
			else if (name.equalsIgnoreCase("ifndef")) {
				String var = c.getParam(0);
				if (!prep.getCompiler().getBooleanParam("compat-tasm")) {
					var = prep.eval(var);
					var = DString.extractString(var);
				}
				if (!Regex.matches("(??word)", var))
					throw new CompileException("ERROR_VAR_REQUIRED", var);
				if (!prep.getCompiler().isDefined(var)) {
					prep.setParsing(true);
					used = true;
				}
				else
					prep.setParsing(false);
			}
			super.parsePersonalDirective(prep, c);
		}

		private String conditional = "";

		public IfBlock(String conditional) {
			super("if", "endif", "else", "elseif", "end");
		}

		public String getConditional() {
			return conditional;
		}
	}
}
